/*
 * Copyright (C) 2007 IsmAvatar <cmagicj@nni.com>
 * 
 * This file is part of Conflict Map Editor (CME).
 * CME is free software and comes with ABSOLUTELY NO WARRANTY.
 * See LICENSE for details.
 */

package org.conflict.main;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;

/** Responsible for handling interaction between .MAP files and UI */
public class FileHandler
	{
	private MapEditor res;
	/**
	 * The last file saved/opened is remembered as <i>chosen</i> for when you click "Save".
	 * This may be useful for something like setting the Title Bar according to the current file.
	 */
	public File chosen;
	private JFileChooser fc;
	private String tiles[][] = { { "N/A","1FS","1FGL","1FGR","1FR","1FB","1FD" },
			{ "N/A","2FB","2FR","2DVU","2DHL","2DHR","2DVD","2SB","2SR","2WG","2WR","2WB","2WD" },
			{ "N/A","3CTL","3CT","3CTR","3CL","3CC","3CR","3CDL","3CD","3CDR" } };
	private HashMap<String,Integer> tileId = new HashMap<String,Integer>();
		{
		for (String[] map : tiles)
			for (int id = 0; id < map.length; id++)
				tileId.put(map[id],id);
		}

	public FileHandler(MapEditor me)
		{
		res = me;
		chosen = null;
		fc = new JFileChooser();
		fc.setFileFilter(new FileNameExtensionFilter("Map files (*.map)","map"));
		fc.setAcceptAllFileFilterUsed(false);
		}

	/** Returns the .MAP-name string for the given tile, without the brackets */
	public String lookup(int tab, int icon)
		{
		return tiles[tab][icon];
		}

	/** Returns the tileID that corresponds to the given .MAP-name, without the brackets */
	public int lookup(String name)
		{
		return tileId.get(name);
		}

	/** Flushes out the UI of all placed tiles, the description, the size, and <i>chosen</i> */
	public void newFile()
		{
		chosen = null;
		res.sDesc.setText("New Map 1");
		res.sWidth.setIntValue(20);
		res.sHeight.setIntValue(20);
		res.ea.flush();
		}

	/** Loads the given .MAP file. There may be a better way to do this. */
	public void load(File f)
		{
		BufferedReader in = null;
		try
			{
			in = new BufferedReader(new FileReader(f));
			res.sDesc.setText(in.readLine().replaceAll("\\[","").split("]")[1]);
			String[] line = in.readLine().replaceAll("\\[","").split("]");
			res.sWidth.setIntValue(Integer.parseInt(line[1]));
			res.sHeight.setIntValue(Integer.parseInt(line[2]));
			for (int j = 0; j < 3; j++)
				for (int i = 0; i < res.sHeight.getIntValue(); i++)
					res.ea.putRow(j,i,in.readLine().replaceAll("\\[","").split("]"));
			}
		catch (IOException e)
			{
			System.out.println("Invalid file format");
			e.printStackTrace();
			}
		catch (NullPointerException e)
			{
			System.out.println("Invalid file format");
			e.printStackTrace();
			}
		try
			{
			if (in != null) in.close();
			}
		catch (IOException e)
			{
			e.printStackTrace();
			}
		}

	/** Checks if there are any missing tiles, and then saves to the given .MAP file */
	public void save(File f)
		{
		if (!res.ea.hasNecessaryObjects()
				&& JOptionPane.showConfirmDialog(res,
						"You are missing a flag or spawn point. Save anyways?","Missing Tile",
						JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) return;
		BufferedWriter out = null;
		int w = res.sWidth.getIntValue();
		int h = res.sHeight.getIntValue();
		try
			{
			out = new BufferedWriter(new FileWriter(f));
			out.write("[Info][" + res.sDesc.getText() + "]");
			out.newLine();
			out.write("[Dimension][" + w + "][" + h + "]");
			out.newLine();
			for (int tab = 0; tab < 3; tab++)
				for (int y = 0; y < h; y++)
					{
					for (int x = 0; x < w; x++)
						out.write("[" + tiles[tab][res.ea.getMapped(tab,x,y)] + "]");
					out.newLine();
					}
			}
		catch (IOException e)
			{
			e.printStackTrace();
			}
		try
			{
			if (out != null) out.close();
			}
		catch (IOException e)
			{
			e.printStackTrace();
			}
		}

	/** Displays a dialog for what file to load in, sets <i>chosen</i>, and calls load(file) */
	public void load()
		{
		if (fc.showOpenDialog(res) != JFileChooser.APPROVE_OPTION) return;
		File f = fc.getSelectedFile();
		while (!f.exists())
			{
			JOptionPane.showMessageDialog(res,f.getName() + "\nFile does not exist. Try again.");
			if (fc.showOpenDialog(res) != JFileChooser.APPROVE_OPTION) return;
			}
		chosen = f;
		load(chosen);
		}

	/** Attempts to save to <i>chosen</i> file, or delegates to saveAs() if there is none */
	public void save()
		{
		if (chosen == null)
			{
			saveAs();
			return;
			}
		save(chosen);
		}

	/** Displays a dialog for what file to save to, sets <i>chosen</i>, and calls save(File) */
	public void saveAs()
		{
		while (true)
			{
			if (fc.showSaveDialog(res) != JFileChooser.APPROVE_OPTION) return;
			String filename = fc.getSelectedFile().getPath();
			if (!filename.endsWith(".map")) filename += ".map";
			File f = new File(filename);
			int result = 0;
			if (f.exists())
				result = JOptionPane.showConfirmDialog(res,filename
						+ " already exists. Do you wish to replace it?","Save File",
						JOptionPane.YES_NO_CANCEL_OPTION,JOptionPane.WARNING_MESSAGE);
			if (result == 0)
				{
				chosen = f;
				save(chosen);
				return;
				}
			if (result == 2) return;
			}
		}
	}
